import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import type { CreateActivityDto, UpdateActivityDto } from './activity.dto';

export interface Activity {
  id: string;
  name: string;
  description: string;
  location: string;
  price: number;
  capacity: number;
  bookedCount: number;
  status: 'active' | 'inactive' | 'full';
  openTime: string;
  closeTime: string;
  createdAt: string;
  updatedAt: string;
}

@Injectable()
export class ActivityService {
  private readonly activitiesFile = path.join(process.cwd(), 'data', 'activities.json');

  constructor() {
    const dataDir = path.join(process.cwd(), 'data');
    if (!fs.existsSync(dataDir)) {
      fs.mkdirSync(dataDir, { recursive: true });
    }

    if (!fs.existsSync(this.activitiesFile)) {
      fs.writeFileSync(this.activitiesFile, JSON.stringify([]));
    }
  }

  private readActivities(): Activity[] {
    const data = fs.readFileSync(this.activitiesFile, 'utf8');
    return JSON.parse(data);
  }

  private writeActivities(activities: Activity[]): void {
    fs.writeFileSync(this.activitiesFile, JSON.stringify(activities, null, 2));
  }

  findAll(): Activity[] {
    return this.readActivities();
  }

  findOneById(id: string): Activity {
    const activities = this.readActivities();
    const activity = activities.find(a => a.id === id);
    if (!activity) {
      throw new Error('Activity not found');
    }
    return activity;
  }

  create(createActivityDto: CreateActivityDto): Activity {
    const activities = this.readActivities();
    const newActivity: Activity = {
      id: Date.now().toString(),
      ...createActivityDto,
      bookedCount: 0,
      status: 'active',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    activities.push(newActivity);
    this.writeActivities(activities);
    return newActivity;
  }

  update(id: string, updateActivityDto: UpdateActivityDto): Activity {
    const activities = this.readActivities();
    const index = activities.findIndex(a => a.id === id);
    if (index === -1) {
      throw new Error('Activity not found');
    }

    activities[index] = {
      ...activities[index],
      ...updateActivityDto,
      updatedAt: new Date().toISOString(),
    };

    this.writeActivities(activities);
    return activities[index];
  }

  remove(id: string): void {
    const activities = this.readActivities();
    const index = activities.findIndex(a => a.id === id);
    if (index === -1) {
      throw new Error('Activity not found');
    }

    activities.splice(index, 1);
    this.writeActivities(activities);
  }

  bookActivity(id: string, bookingId: string): Activity {
    const activities = this.readActivities();
    const index = activities.findIndex(a => a.id === id);
    if (index === -1) {
      throw new Error('Activity not found');
    }

    const activity = activities[index];
    if (activity.status !== 'active') {
      throw new Error('Activity is not available for booking');
    }

    if (activity.bookedCount >= activity.capacity) {
      activity.status = 'full';
      throw new Error('Activity is fully booked');
    }

    activity.bookedCount += 1;
    if (activity.bookedCount >= activity.capacity) {
      activity.status = 'full';
    }

    activity.updatedAt = new Date().toISOString();
    activities[index] = activity;
    this.writeActivities(activities);
    return activity;
  }
}